package s.f.empleados;

import s.f.jndi.ConexionJNDI;
import s.f.util.AppException;
import s.f.util.Conexion;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Clase destinada para el acceso a datos del Empleados.
 * @author froy
 */
public class CRUD_Empleados {

    public static int registrosAfectados;
    /**
     * Realiza una inserción de un Empleado.
     * @param empleados Solicita un objeto Empleado.
     * @throws AppException 
     */
    public static void insertEmpleado(Empleados empleados) throws AppException {
        int index = 1;
        

        StringBuilder sb = new StringBuilder();
        sb.append("insert into sf_emp ");
        sb.append("(nombre,appaterno,apmaterno,fnacimiento");
        sb.append(",email,nss,rfc,curp,sexo,pais,estado,municipio) ");
        sb.append("values (?,?,?,?,?,?,?,?,?,?,?,?)");

        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection();
            PreparedStatement ps = con.prepareStatement(sb.toString());

            ps.setString(index++, empleados.getNombre().trim().toUpperCase());
            ps.setString(index++, empleados.getAppaterno().trim().toUpperCase());
            ps.setString(index++, empleados.getApmaterno().trim().toUpperCase());
            ps.setDate(index++, new java.sql.Date(empleados.getFnacimiento().getTime()));
            ps.setString(index++, empleados.getEmail().trim().toLowerCase());
            ps.setString(index++, empleados.getNss());
            ps.setString(index++, empleados.getRfc().trim().toUpperCase());
            ps.setString(index++, empleados.getCurp().trim().toUpperCase());
            ps.setString(index++, empleados.getSexo().trim().toUpperCase());
            ps.setInt(index++, empleados.getPais());
            ps.setInt(index++, empleados.getEstado());
            ps.setInt(index++, empleados.getMunicipio());

            registrosAfectados = ps.executeUpdate();

            Conexion.closeConnection(con);
        } catch (SQLException sqle) {
            throw new AppException("Fallo al tratar "
                    + "de insertar los datos los datos del empleado.", sqle);
        }
    }
    /**
     * Regresa una collección de todos los empleados existentes.
     * @return Regresa una collección de todos los empleados existentes
     * @throws AppException 
     */
    public static Collection selectEmpleado() throws AppException {
        ArrayList<Map> mapaSelect = new ArrayList<Map>();
        StringBuilder sbQuery = new StringBuilder();
        sbQuery.append("select em.rid,em.nombre,em.appaterno,em.apmaterno,em.fnacimiento, ");
        sbQuery.append("em.email,em.nss,em.rfc,em.curp,em.sexo,p.nombrepais,e.nom_ent,m.nom_mun from sf_emp em ");
        sbQuery.append("left join sf_paises p on em.pais = p.idpais ");
        sbQuery.append("left join sf_estados e on em.estado = e.cve_ent ");
        sbQuery.append("left join sf_municipios m on em.municipio = m.rid ");
        
        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(sbQuery.toString());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                Map m = new HashMap();
                m.put("RID", rs.getInt("rid"));
                m.put("NOMBRE", rs.getString("nombre"));
                m.put("APPATERNO", rs.getString("appaterno"));
                m.put("APMATERNO", rs.getString("apmaterno"));
                m.put("FNACIMINETO", rs.getString("fnacimiento"));
                m.put("EMAIL", rs.getString("email"));
                m.put("NSS", rs.getString("nss"));
                m.put("RFC", rs.getString("rfc"));
                m.put("CURP", rs.getString("curp"));
                m.put("SEXO", rs.getString("sexo"));
                m.put("PAIS", rs.getString("nombrepais"));
                m.put("ESTADO", rs.getString("nom_ent"));
                m.put("MUNICIPIO", rs.getString("nom_mun"));
                mapaSelect.add(m);
            }
            Conexion.closeConnection(con);
        } catch (SQLException sqle) {
            throw new AppException("Fallo al recuperar la lista "
                    + "de todos los empleados", sqle);
        }
        return mapaSelect;
    }
    /**
     * Elimina un empleado por CURP.
     * @param curp Solicita CURP
     * @throws AppException 
     */
    public static void deleteEmpleado(String curp) throws AppException {
        try {
            //Connection con = Conexion.getConnection(); //JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(
                    "delete from sf_emp where curp = ?");
            ps.setString(1, curp);
            registrosAfectados = ps.executeUpdate();
            //Conexion.closeConnection(con);
            ConexionJNDI.closeConnection(con);
        } catch (SQLException sqle) {
            throw new AppException("Fallo al eliminar el empleado", sqle);
        }
    }
    /**
     * Regresa un Map de los empleados si la CURP se encuentra.
     * @param curp Solicita una curp
     * @return Regresa un Map de los registros solicitados por curp
     * @throws AppException 
     */
    public static Map selectEmpleadobyCURP(String curp) throws AppException {
        StringBuilder sbQuery = new StringBuilder();
        sbQuery.append(" select em.rid,em.nombre,em.appaterno,em.apmaterno,em.fnacimiento,");
        sbQuery.append(" em.email,em.nss,em.rfc,em.curp,em.sexo,p.nombrepais,e.nom_ent,m.nom_mun,em.pais,em.estado,em.municipio from sf_emp em ");
        sbQuery.append(" left join sf_paises p on em.pais = p.idpais");
        sbQuery.append(" left join sf_estados e on em.estado = e.cve_ent");
        sbQuery.append(" left join sf_municipios m on em.municipio = m.rid where em.curp=?");
        Map m = new HashMap();

        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(sbQuery.toString());
            ps.setString(1, curp);
            ResultSet rs = ps.executeQuery();

            if (rs.next()) {
                m.put("RID", rs.getInt("rid"));
                m.put("NOMBRE", rs.getString("nombre"));
                m.put("APPATERNO", rs.getString("appaterno"));
                m.put("APMATERNO", rs.getString("apmaterno"));
                m.put("FNACIMINETO", rs.getString("fnacimiento"));
                m.put("EMAIL", rs.getString("email"));
                m.put("NSS", rs.getString("nss"));
                m.put("RFC", rs.getString("rfc"));
                m.put("CURP", rs.getString("curp"));
                m.put("SEXO", rs.getString("sexo"));
                m.put("PAIS", rs.getString("nombrepais"));
                m.put("ESTADO", rs.getString("nom_ent"));
                m.put("MUNICIPIO", rs.getString("nom_mun"));
                
                m.put("idPAIS", rs.getString("pais"));
                m.put("idESTADO", rs.getString("estado"));
                m.put("idMUNICIPIO", rs.getString("municipio"));
            }

            Conexion.closeConnection(con);
        } catch (SQLException sqle) {
            throw new AppException("Fallo al recuperar los "
                    + "datos de un empleado.", sqle);
        }
        return m;
    }
    /**
     * Obtener si el existen duplicados en determinada columna CURP RFC o NSS.
     * @param columna Nombre de columnas admitidas "curp" "rfc" y "nss"
     * @param elemento Solicitud de la cadena de texto dependiendo de la columna.
     * @return Regresa true si encuentra datos dublicados en otro caso false.
     * @throws AppException 
     */
    public static boolean getDuplicados(String columna, String elemento) throws AppException {
        boolean evaluarDuplicado = false;

        String query = "";
        if (columna.equals("curp")) {
            query = "select * from sf_emp where curp=?";
        } else if (columna.equals("rfc")) {
            query = "select * from sf_emp where rfc=?";
        } else if (columna.equals("nss")) {
            query = "select * from sf_emp where nss=?";
        }

        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(query);
            ps.setString(1, elemento);
            ResultSet rs = ps.executeQuery();
            evaluarDuplicado = rs.next();
            Conexion.closeConnection(con);

        } catch (SQLException sqle) {
            throw new AppException("Fallo al tratar de obtener "
                    + "los datos duplicados de la curp,rfc o nss.", sqle);
        }
        return evaluarDuplicado;
    }
    /**
     * Obtener si el NSS se encuntra duplicado en determinada CURP.
     * @param NSS Solicita el NSS
     * @param CURP Solicita la CURP
     * @return Regresa true si encuentra datos dublicados en otro caso false.
     * @throws AppException 
     */
    public static boolean getDuplicadoNSSbyCURP(String NSS, String CURP) throws AppException {
        boolean evaluarDuplicado = false;
        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(
                    "SELECT * FROM sf_emp WHERE curp != ? and nss = ?");
            ps.setString(1, CURP);
            ps.setString(2, NSS);
            ResultSet rs = ps.executeQuery();

            evaluarDuplicado = rs.next();
            Conexion.closeConnection(con);
        } catch (SQLException ex) {
            throw new AppException("Fallo al tratar de obtener los "
                    + "datos duplicados del nss por medio de la curp.", ex);
        }
        return evaluarDuplicado;
    }
    /**
     * Obtener si el RFC se encuntra duplicado en determinada CURP.
     * @param RFC Solicita el RFC
     * @param CURP Solicita la CURP
     * @return Regresa true si encuentra datos dublicados en otro caso false.
     * @throws AppException 
     */
    public static boolean getDuplicadoRFCbyCURP(String RFC, String CURP) throws AppException {
        boolean val = false;
        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(
                    "select * from sf_emp where curp != ? and rfc = ?");
            ps.setString(1, CURP);
            ps.setString(2, RFC);
            ResultSet rs = ps.executeQuery();
            val = rs.next();
            Conexion.closeConnection(con);
        } catch (SQLException ex) {
            throw new AppException("Fallo al tratar de obtener los "
                    + "datos duplicados del rfc por medio de la curp.", ex);
        }
        return val;
    }
    /**
     * 
     * @param arregloEmpleado
     * @throws AppException 
     * @deprecated Actualmente no se esta utilizando.
     */
    public static void updateEmpleado(String[] arregloEmpleado) throws AppException {
        StringBuilder sb = new StringBuilder();
        int index = 1;
        sb.append("update sf_emp ");
        sb.append("set nombre = ?,appaterno = ?,apmaterno = ?,fnacimiento = ?");
        sb.append(",email = ?,nss = ?,rfc = ?,sexo = ?,pais = ?,estado = ?,municipio = ?) ");
        sb.append("where curp=?");

        java.sql.Date fecFormatoDate = null;
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy", new Locale("es", "MX"));

        try {
            fecFormatoDate = new java.sql.Date(sdf.parse(String.valueOf(arregloEmpleado[3])).getTime());
        } catch (ParseException pe) {
            throw new AppException("Fallo al convertir formato de fecha", pe);
        }

        try {
            //Connection con = Conexion.getConnection(); JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(sb.toString());

            ps.setString(index++, arregloEmpleado[0].trim().toUpperCase());
            ps.setString(index++, arregloEmpleado[1].trim().toUpperCase());
            ps.setString(index++, arregloEmpleado[2].trim().toUpperCase());
            ps.setDate(index++, fecFormatoDate);
            //ps.setDate(index++, sqlDate);
            ps.setString(index++, arregloEmpleado[4].trim().toLowerCase());
            ps.setString(index++, arregloEmpleado[5]);
            ps.setString(index++, arregloEmpleado[6].trim().toUpperCase());
            ps.setString(index++, arregloEmpleado[7].trim().toUpperCase());
            ps.setString(index++, arregloEmpleado[8].trim().toUpperCase());
            //ps.setInt(index++, arregloEmpleado[9]);
            ps.setString(index++, arregloEmpleado[10].trim().toUpperCase());
            ps.setString(index++, arregloEmpleado[11].trim().toUpperCase());

            registrosAfectados = ps.executeUpdate();
            Conexion.closeConnection(con);

        } catch (SQLException ex) {
            throw new AppException("Fallo al tratar de actualizar los datos.", ex);
        }
    }
    /**
     * Actualiza los datos de un empleado.
     * @param empleados Solicita objeto Empleado
     * @throws AppException 
     */
    public static void updateEmpleado(Empleados empleados) throws AppException {
        int index = 1; //Utilizado como indice en la inserción del ps.

        StringBuilder sb = new StringBuilder();
        sb.append("update sf_emp ");
        sb.append("set nombre = ?,appaterno = ?,apmaterno = ?,fnacimiento = ?");
        sb.append(",email = ?,nss = ?,rfc = ?,sexo = ?,pais = ?,estado = ?,municipio = ? ");
        sb.append("where curp=?");

        try {
            //Connection con = Conexion.getConnection(); //JDBC
            Connection con = ConexionJNDI.getConnection(); //JNDI
            PreparedStatement ps = con.prepareStatement(sb.toString());
            
            ps.setString(index++, empleados.getNombre().trim().toUpperCase());
            ps.setString(index++, empleados.getAppaterno().trim().toUpperCase());
            ps.setString(index++, empleados.getApmaterno().trim().toUpperCase());
            ps.setDate(index++, new java.sql.Date(empleados.getFnacimiento().getTime()));
            ps.setString(index++, empleados.getEmail().trim().toLowerCase());
            ps.setString(index++, empleados.getNss());
            ps.setString(index++, empleados.getRfc().trim().toUpperCase());
            ps.setString(index++, empleados.getSexo().trim().toUpperCase());
            ps.setInt(index++, empleados.getPais());
            ps.setInt(index++, empleados.getEstado());
            ps.setInt(index++, empleados.getMunicipio());
            ps.setString(index++, empleados.getCurp().trim().toUpperCase());

            registrosAfectados = ps.executeUpdate();
            Conexion.closeConnection(con);

        } catch (SQLException sqle) {
            throw new AppException("Fallo al tratar de "
                    + "actualizar los datos.", sqle);
        }
    }
}